<template>
  <div class="trace-stats-container">
    <el-row :gutter="20">
      <!-- 统计卡片 -->
      <el-col :xs="24" :sm="12" :md="6" v-for="(card, index) in dataCards" :key="index">
        <el-card class="data-card" :body-style="{ padding: '20px' }">
          <div class="card-content">
            <el-icon :size="40" :color="card.color">
              <component :is="card.icon"></component>
            </el-icon>
            <div class="card-info">
              <div class="card-value">{{ card.value }}</div>
              <div class="card-title">{{ card.title }}</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="chart-row">
      <!-- 溯源码扫描地区分布 -->
      <el-col :xs="24" :md="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>溯源码扫描地区分布</span>
            </div>
          </template>
          <div id="locationChart" class="chart-container"></div>
        </el-card>
      </el-col>

      <!-- 溯源码扫描趋势 -->
      <el-col :xs="24" :md="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>溯源码扫描趋势</span>
              <el-radio-group v-model="trendTimeRange" size="small" @change="fetchScanTrend">
                <el-radio-button label="week">近一周</el-radio-button>
                <el-radio-button label="month">近一月</el-radio-button>
                <el-radio-button label="year">近一年</el-radio-button>
              </el-radio-group>
            </div>
          </template>
          <div id="trendChart" class="chart-container"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="chart-row">
      <!-- 产品扫描排行 -->
      <el-col :xs="24" :md="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>产品扫描排行</span>
              <el-select v-model="productRankLimit" size="small" @change="fetchTopProducts">
                <el-option :value="5" label="Top 5"></el-option>
                <el-option :value="10" label="Top 10"></el-option>
                <el-option :value="20" label="Top 20"></el-option>
              </el-select>
            </div>
          </template>
          <el-table :data="topProducts" style="width: 100%" stripe>
            <el-table-column type="index" width="50" label="排名" />
            <el-table-column prop="productName" label="产品名称" />
            <el-table-column prop="batchNumber" label="批次号" width="100" />
            <el-table-column prop="scanCount" label="扫描次数" width="100" align="right" />
            <el-table-column prop="ratio" label="占比" width="100" align="right">
              <template #default="scope">
                <span>{{ scope.row.ratio }}%</span>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>

      <!-- 用户扫描设备分布 -->
      <el-col :xs="24" :md="12">
        <el-card class="chart-card">
          <template #header>
            <div class="card-header">
              <span>用户扫描设备分布</span>
            </div>
          </template>
          <div id="deviceChart" class="chart-container"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 最近扫描记录 -->
    <el-card class="log-card">
      <template #header>
        <div class="card-header">
          <span>最近扫描记录</span>
          <el-button type="primary" size="small" @click="fetchRecentScans">刷新</el-button>
        </div>
      </template>
      <el-table :data="recentScans" style="width: 100%" v-loading="loading.recentScans">
        <el-table-column prop="code" label="溯源码" width="170" />
        <el-table-column prop="productName" label="产品名称" />
        <el-table-column prop="location" label="扫描地点" width="150" />
        <el-table-column prop="deviceType" label="设备类型" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.deviceType === 'Mobile' ? 'success' : 'primary'">
              {{ scope.row.deviceType === 'Mobile' ? '移动端' : '电脑端' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="browser" label="浏览器" width="120" />
        <el-table-column prop="scanTime" label="扫描时间" width="180" />
        <el-table-column label="操作" width="80" fixed="right">
          <template #default="scope">
            <el-button type="text" size="small" @click="viewScanDetail(scope.row)">
              详情
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="scanQuery.page"
          v-model:page-size="scanQuery.size"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="scanTotal"
          @size-change="handleScanSizeChange"
          @current-change="handleScanPageChange"
        />
      </div>
    </el-card>

    <!-- 扫描详情对话框 -->
    <el-dialog v-model="detailVisible" title="扫描详情" width="700px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="溯源码">{{ selectedScan.code }}</el-descriptions-item>
        <el-descriptions-item label="扫描时间">{{ selectedScan.scanTime }}</el-descriptions-item>
        <el-descriptions-item label="产品名称">{{ selectedScan.productName }}</el-descriptions-item>
        <el-descriptions-item label="批次号">{{ selectedScan.batchNumber }}</el-descriptions-item>
        <el-descriptions-item label="扫描地点">{{ selectedScan.location }}</el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ selectedScan.ipAddress }}</el-descriptions-item>
        <el-descriptions-item label="设备类型">
          <el-tag :type="selectedScan.deviceType === 'Mobile' ? 'success' : 'primary'">
            {{ selectedScan.deviceType === 'Mobile' ? '移动端' : '电脑端' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="浏览器">{{ selectedScan.browser }}</el-descriptions-item>
        <el-descriptions-item label="操作系统" :span="2">{{ selectedScan.os }}</el-descriptions-item>
        <el-descriptions-item label="用户代理" :span="2">
          <div class="ua-text">{{ selectedScan.userAgent }}</div>
        </el-descriptions-item>
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import {
  View,
  Timer,
  Location,
  Histogram
} from '@element-plus/icons-vue'

// 模拟数据
const mockData = {
  overview: {
    totalTraceQueries: 82,
    todayTraceQueries: 42,
    traceQueryLocationCount: 6,
    queriedProductCount: 123
  },
  locationDistribution: [
    { name: '北京', value: 1256 },
    { name: '上海', value: 986 },
    { name: '广州', value: 752 },
    { name: '深圳', value: 625 },
    { name: '成都', value: 521 },
    { name: '杭州', value: 490 },
    { name: '武汉', value: 432 },
    { name: '南京', value: 375 },
    { name: '西安', value: 312 },
    { name: '其他', value: 1023 }
  ],
  trendData: {
    week: [
      { date: '星期一', count: 126 },
      { date: '星期二', count: 145 },
      { date: '星期三', count: 158 },
      { date: '星期四', count: 142 },
      { date: '星期五', count: 187 },
      { date: '星期六', count: 221 },
      { date: '星期日', count: 198 }
    ],
    month: Array.from({ length: 30 }, (_, i) => ({
      date: `${i + 1}日`,
      count: Math.floor(Math.random() * 100) + 100
    })),
    year: Array.from({ length: 12 }, (_, i) => ({
      date: `${i + 1}月`,
      count: Math.floor(Math.random() * 1000) + 500
    }))
  },
  topProducts: Array.from({ length: 20 }, (_, i) => ({
    productName: `宁夏枸杞${i + 1}号`,
    batchNumber: `B${String(2023001 + i).padStart(7, '0')}`,
    scanCount: Math.floor(Math.random() * 500) + 100
  })),
  deviceDistribution: [
    { name: '手机', value: 6 },
    { name: '电脑', value: 4 },
    { name: '平板', value: 1632 }
  ],
  recentScans: Array.from({ length: 100 }, (_, i) => {
    const deviceTypes = ['Mobile', 'Desktop', 'Tablet'];
    const browsers = ['Chrome', 'Safari', 'Firefox', 'Edge', 'IE'];
    const locations = ['北京', '上海', '广州', '深圳', '成都', '杭州', '武汉', '南京', '西安'];
    const productNames = ['高档枸杞', '特级枸杞', '中级枸杞', '普通枸杞'];

    const deviceType = deviceTypes[Math.floor(Math.random() * deviceTypes.length)];
    const browser = browsers[Math.floor(Math.random() * browsers.length)];
    const location = locations[Math.floor(Math.random() * locations.length)];
    const productName = productNames[Math.floor(Math.random() * productNames.length)];

    // 生成最近30天内的随机时间
    const now = new Date();
    const randomDate = new Date(now.getTime() - Math.floor(Math.random() * 30) * 24 * 60 * 60 * 1000);
    const scanTime = randomDate.toISOString().replace('T', ' ').substring(0, 19);

    return {
      id: i + 1,
      code: `TR${String(Math.floor(Math.random() * 9000000) + 1000000)}`,
      productName: `${productName}${Math.floor(Math.random() * 10) + 1}号`,
      batchNumber: `B${String(2023001 + Math.floor(Math.random() * 100)).padStart(7, '0')}`,
      location: location,
      deviceType: deviceType,
      browser: browser,
      scanTime: scanTime,
      ipAddress: `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`,
      os: deviceType === 'Mobile' ? 'Android' : 'Windows',
      userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    };
  })
};

export default {
  name: 'TraceStats',
  components: {
    View,
    Timer,
    Location,
    Histogram
  },
  setup() {
    // 图表实例
    let locationChart = null
    let trendChart = null
    let deviceChart = null

    // 数据卡片
    const dataCards = ref([
      {
        title: '总扫描次数',
        value: 0,
        icon: 'View',
        color: '#409EFF'
      },
      {
        title: '今日扫描次数',
        value: 0,
        icon: 'Timer',
        color: '#67C23A'
      },
      {
        title: '扫描地区数',
        value: 0,
        icon: 'Location',
        color: '#E6A23C'
      },
      {
        title: '产品扫描数',
        value: 0,
        icon: 'Histogram',
        color: '#F56C6C'
      }
    ])

    // 时间范围
    const trendTimeRange = ref('week')

    // 产品排行限制
    const productRankLimit = ref(5)

    // 最热门产品
    const topProducts = ref([])

    // 最近扫描记录
    const recentScans = ref([])
    const scanTotal = ref(0)
    const scanQuery = reactive({
      page: 1,
      size: 5
    })

    // 扫描详情
    const detailVisible = ref(false)
    const selectedScan = ref({})

    // 加载状态
    const loading = reactive({
      overview: false,
      location: false,
      trend: false,
      products: false,
      device: false,
      recentScans: false
    })

    // 获取概览数据 - 使用模拟数据
    const fetchOverviewData = async () => {
      loading.overview = true
      try {
        // 使用模拟数据
        const data = mockData.overview;

        // 更新数据卡片
        dataCards.value[0].value = data.totalTraceQueries || 0
        dataCards.value[1].value = data.todayTraceQueries || 0
        dataCards.value[2].value = data.traceQueryLocationCount || 0
        dataCards.value[3].value = data.queriedProductCount || 0

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 300));
      } catch (error) {
        console.error('获取统计概览失败:', error)
        ElMessage.error('获取统计概览失败: ' + (error.message || '未知错误'))
      } finally {
        loading.overview = false
      }
    }

    // 获取地区分布数据 - 使用模拟数据
    const fetchLocationData = async () => {
      loading.location = true
      try {
        // 使用模拟数据
        const data = mockData.locationDistribution;

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 500));

        initLocationChart(data);
      } catch (error) {
        console.error('获取地区分布数据失败:', error)
        ElMessage.error('获取地区分布数据失败: ' + (error.message || '未知错误'))
      } finally {
        loading.location = false
      }
    }

    // 获取趋势数据 - 使用模拟数据
    const fetchScanTrend = async () => {
      loading.trend = true
      try {
        // 根据选择的时间范围获取数据
        const period = trendTimeRange.value

        // 使用模拟数据
        const data = mockData.trendData[period];

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 400));

        initTrendChart(data);
      } catch (error) {
        console.error('获取趋势数据失败:', error)
        ElMessage.error('获取趋势数据失败: ' + (error.message || '未知错误'))
      } finally {
        loading.trend = false
      }
    }

    // 获取热门产品数据 - 使用模拟数据
    const fetchTopProducts = async () => {
      loading.products = true
      try {
        const limit = productRankLimit.value

        // 使用模拟数据
        const data = mockData.topProducts.slice(0, limit);

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 300));

        // 计算占比
        const total = data.reduce((sum, item) => sum + item.scanCount, 0)

        topProducts.value = data.map(item => ({
          ...item,
          ratio: ((item.scanCount / total) * 100).toFixed(2)
        }));
      } catch (error) {
        console.error('获取热门产品数据失败:', error)
        ElMessage.error('获取热门产品数据失败: ' + (error.message || '未知错误'))
      } finally {
        loading.products = false
      }
    }

    // 获取设备分布数据 - 使用模拟数据
    const fetchDeviceData = async () => {
      loading.device = true
      try {
        // 使用模拟数据
        const data = mockData.deviceDistribution;

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 400));

        initDeviceChart(data);
      } catch (error) {
        console.error('获取设备分布数据失败:', error)
        ElMessage.error('获取设备分布数据失败: ' + (error.message || '未知错误'))
      } finally {
        loading.device = false
      }
    }

    // 获取最近扫描记录 - 使用模拟数据
    const fetchRecentScans = async () => {
      loading.recentScans = true
      try {
        // 使用模拟数据，模拟分页效果
        const { page, size } = scanQuery;
        const startIndex = (page - 1) * size;
        const endIndex = startIndex + size;

        // 模拟网络延迟
        await new Promise(resolve => setTimeout(resolve, 500));

        recentScans.value = mockData.recentScans.slice(startIndex, endIndex);
        scanTotal.value = mockData.recentScans.length;
      } catch (error) {
        console.error('获取扫描记录失败:', error)
        ElMessage.error('获取扫描记录失败: ' + (error.message || '未知错误'))
      } finally {
        loading.recentScans = false
      }
    }

    // 查看扫描详情
    const viewScanDetail = (row) => {
      selectedScan.value = { ...row }
      detailVisible.value = true
    }

    // 初始化地区分布图表
    const initLocationChart = (data) => {
      if (!locationChart) {
        locationChart = echarts.init(document.getElementById('locationChart'))

        // 监听窗口大小变化
        window.addEventListener('resize', () => locationChart.resize())
      }

      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          right: 10,
          top: 'center',
          data: data.map(item => item.name)
        },
        series: [
          {
            name: '扫描地区',
            type: 'pie',
            radius: ['40%', '70%'],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 10,
              borderColor: '#fff',
              borderWidth: 2
            },
            label: {
              show: false,
              position: 'center'
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '16',
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            data: data.map(item => ({
              name: item.name,
              value: item.value
            }))
          }
        ]
      }

      locationChart.setOption(option)
    }

    // 初始化趋势图表
    const initTrendChart = (data) => {
      if (!trendChart) {
        trendChart = echarts.init(document.getElementById('trendChart'))

        // 监听窗口大小变化
        window.addEventListener('resize', () => trendChart.resize())
      }

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        xAxis: {
          type: 'category',
          data: data.map(item => item.date),
          axisLabel: {
            interval: 0,
            rotate: trendTimeRange.value === 'month' ? 30 : 0
          }
        },
        yAxis: {
          type: 'value',
          name: '扫描次数'
        },
        series: [
          {
            name: '扫描次数',
            type: 'bar',
            data: data.map(item => item.count),
            itemStyle: {
              color: '#409EFF'
            },
            emphasis: {
              itemStyle: {
                color: '#66b1ff'
              }
            }
          }
        ],
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        }
      }

      trendChart.setOption(option)
    }

    // 初始化设备分布图表
    const initDeviceChart = (data) => {
      if (!deviceChart) {
        deviceChart = echarts.init(document.getElementById('deviceChart'))

        // 监听窗口大小变化
        window.addEventListener('resize', () => deviceChart.resize())
      }

      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          right: 10,
          top: 'center',
          data: data.map(item => item.name)
        },
        series: [
          {
            name: '设备类型',
            type: 'pie',
            radius: '60%',
            center: ['40%', '50%'],
            data: data.map(item => ({
              name: item.name,
              value: item.value
            })),
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      }

      deviceChart.setOption(option)
    }

    // 分页相关
    const handleScanSizeChange = (newSize) => {
      scanQuery.size = newSize
      fetchRecentScans()
    }

    const handleScanPageChange = (newPage) => {
      scanQuery.page = newPage
      fetchRecentScans()
    }

    // 生命周期钩子
    onMounted(() => {
      fetchOverviewData()
      fetchLocationData()
      fetchScanTrend()
      fetchTopProducts()
      fetchDeviceData()
      fetchRecentScans()
    })

    onUnmounted(() => {
      // 销毁图表实例
      locationChart && locationChart.dispose()
      trendChart && trendChart.dispose()
      deviceChart && deviceChart.dispose()

      // 移除事件监听
      window.removeEventListener('resize', () => locationChart.resize())
      window.removeEventListener('resize', () => trendChart.resize())
      window.removeEventListener('resize', () => deviceChart.resize())
    })

    return {
      dataCards,
      trendTimeRange,
      productRankLimit,
      topProducts,
      recentScans,
      scanTotal,
      scanQuery,
      loading,
      detailVisible,
      selectedScan,
      fetchScanTrend,
      fetchTopProducts,
      fetchRecentScans,
      viewScanDetail,
      handleScanSizeChange,
      handleScanPageChange
    }
  }
}
</script>

<style scoped>
.trace-stats-container {
  padding: 20px;
}

.data-card {
  margin-bottom: 20px;
  height: 120px;
}

.card-content {
  display: flex;
  align-items: center;
}

.card-info {
  margin-left: 20px;
}

.card-value {
  font-size: 28px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 5px;
}

.card-title {
  font-size: 14px;
  color: #909399;
}

.chart-row {
  margin-bottom: 20px;
}

.chart-card {
  margin-bottom: 20px;
}

.chart-container {
  height: 350px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.log-card {
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.ua-text {
  word-break: break-all;
  max-height: 80px;
  overflow-y: auto;
  font-size: 12px;
  font-family: monospace;
}
</style>
